package com.chat.room.client;

import com.chat.room.bean.ServerInfo;
import com.chat.room.common.ClientConstant;
import com.chat.room.common.CommonConstant;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.net.*;
import java.nio.ByteBuffer;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * 服务器查找对象类
 */
@Slf4j
@Data
public class ServiceSearch {

    private DatagramSocket datagramSocket;

    private int searchListenerPort;

    private Listener listener;

    private List<ServerInfo> serverInfoList = new CopyOnWriteArrayList<>();

    public ServiceSearch(DatagramSocket datagramSocket,int searchListenerPort) {
        this.datagramSocket = datagramSocket;
        this.searchListenerPort = searchListenerPort;
    }

    public void listener() {
        if (null == listener) {
            listener = new Listener(true);
            ClientConstant.THREAD_POOL_EXECUTOR.execute(listener);
        }
    }

    public void close() {
        if (null != listener) {
            listener.setFlag(false);
        }
        if (null != datagramSocket) {
            datagramSocket.close();
        }
        log.info("关闭服务发现监听");
    }

    public void searchSend() throws IOException {
        log.info("开始广播搜索服务器");
        byte[] bytes = (CommonConstant.COMMONS_SEARCH_INFO + searchListenerPort).getBytes();
        DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length);
        datagramPacket.setPort(CommonConstant.SEARCH_PORT);
        datagramPacket.setAddress(Inet4Address.getByName("255.255.255.255"));
        datagramSocket.send(datagramPacket);
    }

    /**
     * 添加服务配置
     *
     * @param server
     */
    public void addServiceInfo(ServerInfo server) {
        for (ServerInfo serverInfo : serverInfoList) {
            if (serverInfo.getPort() == server.getPort() && serverInfo.getIp().equals(server.getIp())) {
                return;
            }
        }
        log.info("加入服务器对象：{}",server);
        serverInfoList.add(server);
    }

    /**
     * 服务监听对象
     */
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    private class Listener implements Runnable {

        private boolean flag;

        @Override
        public void run() {
            byte[] bytes = new byte[256];
            DatagramPacket datagramPacket = new DatagramPacket(bytes, 0, 256);
            while (flag) {
                try {
                    log.info("客户端开始监听端口：{}", searchListenerPort);

                    datagramSocket.receive(datagramPacket);
                    ByteBuffer byteBuffer = ByteBuffer.wrap(datagramPacket.getData());
                    /*获取到服务器端口号*/
                    int port = byteBuffer.getInt();
                    InetAddress address = datagramPacket.getAddress();
                    int responsePort = datagramPacket.getPort();
                    log.info("接收到服务器{}:{}返回消息", address, responsePort);
                    log.info("获取到服务器连接端口号：{}", port);
                    addServiceInfo(new ServerInfo(address, port));
                } catch (IOException e) {
                    log.error("连接关闭");
                }
            }
        }
    }


}